package com.young.hzh_learning;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;

import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author huangzehui
 * @date 10/8/2024 上午10:14 周六
 * @description 摇一摇的处理
 *
 * https://developer.aliyun.com/article/253653
 */
public class ShakeListener implements SensorEventListener, LifecycleEventObserver {
    String TAG = "ShakeListener";
    // 速度阈值，当摇晃速度达到这值后产生作用
    private static final int SPEED_SHRESHOLD = 3000;
    // 两次检测的时间间隔
    private static final int UPTATE_INTERVAL_TIME = 70;
    // 传感器管理器
    private SensorManager sensorManager;
    // 传感器
    private Sensor sensor;
    // 重力感应监听器
    private OnShakeListener onShakeListener;
    // 上下文
    private Context mContext;
    // 手机上一个位置时重力感应坐标
    private float lastX;
    private float lastY;
    private float lastZ;
    // 上次检测时间
    private long lastUpdateTime;

    // young 新增，是否触发了回调
    private AtomicBoolean isTrigger = new AtomicBoolean(false);

    // 延迟任务的延迟时间，单位：ms
    private long triggerDelayTime = 1500;

    // Handler
    private Handler mHandler = new Handler(Looper.getMainLooper());

    // 延时任务
    private Runnable delayTask = new Runnable() {
        @Override
        public void run() {
            isTrigger.set(false);
        }
    };

    // 是否首次
    private boolean isFirstResume = true;

    // 是否开启日志
    private boolean isLog = false;

    /**
     * @param c                上下文
     * @param triggerDelayTime 延迟任务的延迟时间，单位：ms
     */
    public ShakeListener(Context c, long triggerDelayTime) {
        // 获得监听对象
        mContext = c;
        if (triggerDelayTime < 0) {
            this.triggerDelayTime = triggerDelayTime;
        }
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
        if (event == Lifecycle.Event.ON_DESTROY) {
            removeDelayTask();
        } else if (event == Lifecycle.Event.ON_RESUME) {
            if (isFirstResume){
                isFirstResume = false;
            } else {
                start();
            }
        } else if (event == Lifecycle.Event.ON_PAUSE) {
            stop();
        }
    }

    /**
     * 移除延时任务，提前移除，就可以提前再次触发摇一摇
     */
    public void removeDelayTask() {
        mHandler.removeCallbacks(delayTask);
    }

    // 开始
    public void start() {
        if (sensorManager == null) {
            // 获得传感器管理器
            sensorManager = (SensorManager) mContext
                    .getSystemService(Context.SENSOR_SERVICE);
            if (sensorManager != null) {
                // 获得重力传感器
                sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
            }
        }

        // 注册
        if (sensor != null && sensorManager != null) {
            sensorManager.registerListener(this, sensor,
                    SensorManager.SENSOR_DELAY_GAME);
        }
    }

    // 停止检测
    public void stop() {
        if (sensorManager != null) {
            sensorManager.unregisterListener(this);
        }
    }

    // 设置重力感应监听器
    public void setOnShakeListener(OnShakeListener listener) {
        onShakeListener = listener;
    }

    // 重力感应器感应获得变化数据
    public void onSensorChanged(SensorEvent event) {
        // 现在检测时间
        long currentUpdateTime = System.currentTimeMillis();
        // 两次检测的时间间隔
        long timeInterval = currentUpdateTime - lastUpdateTime;
        // 判断是否达到了检测时间间隔
        if (timeInterval < UPTATE_INTERVAL_TIME)
            return;
        // 现在的时间变成last时间
        lastUpdateTime = currentUpdateTime;
        // 获得x,y,z坐标
        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];
        // 获得x,y,z的变化值
        float deltaX = x - lastX;
        float deltaY = y - lastY;
        float deltaZ = z - lastZ;
        // 将现在的坐标变成last坐标
        lastX = x;
        lastY = y;
        lastZ = z;
        double speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ
                * deltaZ)
                / timeInterval * 10000;
        if (isLog){
            Log.v(TAG, "===========log===================");
            Log.i(TAG, "x轴方向的重力加速度" + x + "；y轴方向的重力加速度" + y + "；z轴方向的重力加速度" + z);
        }
        // 达到速度阀值，发出提示
        if (speed >= SPEED_SHRESHOLD) {
            if (!isTrigger.get()) {
                onShakeListener.onShake();
                isTrigger.set(true);
                mHandler.postDelayed(delayTask, 2000);
            }
        }
    }

    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }


    // 摇晃监听接口
    public interface OnShakeListener {
        public void onShake();
    }
}
